/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.google.code.fishing.gui;

/**
 *
 * @author kraessig
 */
import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.DisplayMode;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
 
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JWindow;
 
/**
 * @author Tom
 * 
 */
public class FadingLoadingScreen {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        FadingSplashScreen fadingSplashScreen = new FadingSplashScreen(
                "logo2.gif",
                32,
                3);
        fadingSplashScreen.setVisible(true);
        fadingSplashScreen.setFinishedCallback(new Runnable() {
            public void run() {
                MainFrame frm = new MainFrame();
                frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frm.setSize(500,420);
                frm.setLocationRelativeTo(null);
                frm.setVisible(true);
                
            }
        });
        fadingSplashScreen.startFading();
 
    }
 
    static class FadingSplashScreen extends JWindow {
        String pathToSplashScreenImage;
 
        int numberOfSecondsToShow;
 
        BufferedImage splashScreenImage;
 
        BufferedImage fadedSplashScreenImage;
 
        BufferedImage screenShot;
 
        ExecutorService fadingExecutor;
 
        Runnable fadingCommand;
 
        Runnable finishedCallback;
 
        int numberOfFadingSteps;
 
        /**
         * @param pathToSplashScreenImage
         * @param numberOfSecondsToShow
         * @param
         */
        public FadingSplashScreen(String pathToSplashScreenImage,
                int numberOfFadingSteps, int numberOfSecondsToShow) {
            super();
            this.numberOfFadingSteps = numberOfFadingSteps;
            this.pathToSplashScreenImage = pathToSplashScreenImage;
            this.numberOfSecondsToShow = numberOfSecondsToShow;
            init();
        }
 
        public void setFinishedCallback(Runnable finishedCallback) {
            this.finishedCallback = finishedCallback;
        }
 
        public void startFading() {
            fadingExecutor.execute(fadingCommand);
        }
 
        private void init() {
            try {
                this.splashScreenImage = loadSplashScreenImage();
                this.screenShot = makeScreenShot(
                        splashScreenImage.getWidth(),
                        splashScreenImage.getHeight());
                setSize(splashScreenImage.getWidth(), splashScreenImage
                        .getHeight());
                setLocationRelativeTo(null);
                this.fadingCommand = new Runnable() {
                    public void run() {
 
                        fadedSplashScreenImage = splashScreenImage;
                        repaint();
 
                        try {
                            TimeUnit.SECONDS.sleep(numberOfSecondsToShow);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
 
                        float alpha = 1.0F;
                        float alphaFactor = 1.0F / numberOfFadingSteps;
                        for (int i = 0; i < numberOfFadingSteps; i++) {
                            float currentAlpha = alpha - i * alphaFactor;
                            fadedSplashScreenImage = fadeSplashImage(AlphaComposite
                                    .getInstance(
                                            AlphaComposite.SRC_OVER,
                                            currentAlpha));
                            //System.out.println(currentAlpha);
                            repaint();
                            try {
                                TimeUnit.MILLISECONDS.sleep(50);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        setVisible(false);
                        dispose();
                        finishedCallback.run();
                    }
                };
                this.fadingExecutor = Executors.newSingleThreadExecutor();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
        private BufferedImage fadeSplashImage(AlphaComposite composite) {
            BufferedImage bufferedImage = new BufferedImage(
                    splashScreenImage.getWidth(),
                    splashScreenImage.getHeight(),
                    BufferedImage.TYPE_INT_ARGB);
 
            Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
            g.drawImage(screenShot, 0, 0, null);
            g.setComposite(composite);
            g.drawImage(splashScreenImage, 0, 0, null);
 
            return bufferedImage;
        }
 
        private BufferedImage makeScreenShot(int width, int height)
                throws AWTException {
            Robot robot = new Robot();
            DisplayMode displayMode = GraphicsEnvironment
                    .getLocalGraphicsEnvironment()
                    .getDefaultScreenDevice()
                    .getDisplayMode();
 
            return robot.createScreenCapture(new Rectangle(
                    displayMode.getWidth() / 2 - width / 2,
                    displayMode.getHeight() / 2 - height / 2,
                    width,
                    height));
        }
 
        private BufferedImage loadSplashScreenImage() throws IOException {
            return ImageIO.read(getClass().getResource("/com/google/code/fishing/images/" + pathToSplashScreenImage));
        }
 
        public void paint(Graphics g) {
            g.drawImage(fadedSplashScreenImage, 0, 0, null);
        }
    }
}
